#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <utility>
using namespace std;

typedef set <int> Set;
typedef Set::iterator Sit;
typedef multiset <int> Mset;
typedef Mset::iterator Msit;
typedef map <Mset, double> Map;
typedef Map::iterator Mit;
typedef map <int, Set> Tree;
typedef Tree::iterator Trit;

#define for_it(it,cont) for (it = cont.begin(); it != cont.end(); ++it)

template <typename E>
ostream & operator << (ostream &os, const set <E> &s)
{
	typename set <E>::const_iterator it;
	os << '{';
	if (! s.empty ())
	{
		it = s.begin ();
		os << *it;
		for (++it; it != s.end (); ++it)
			os << ", " << *it;
	}
	os << '}';
	return os;
}

template <typename E>
ostream & operator << (ostream &os, const multiset <E> &s)
{
	typename multiset <E>::const_iterator it;
	os << '{';
	if (! s.empty ())
	{
		it = s.begin ();
		os << *it;
		for (++it; it != s.end (); ++it)
			os << ", " << *it;
	}
	os << '}';
	return os;
}

template <typename A, typename B>
ostream & operator << (ostream &os, const map <A, B> &m)
{
	typename map <A, B>::const_iterator it;
	os << '[';
	for (it = m.begin (); it != m.end (); ++it)
		os << '\t' << it->first << ": " << it->second << '\n';
	os << ']';
}

/********************************************************************/


Map prob;
Tree tree;

void init (int n)
{
	Mset s;
	s.insert (n);
	prob.clear();
	tree.clear();
	prob[s] = 1.0;
}


int tree_dfs (vector <bool> &marked, int node)
{
	if (marked[node])
		return 0;
	Sit it;
	int result = 1;
	marked[node] = true;
	Set &tn = tree[node];
	for_it (it, tn)
	{
		result += tree_dfs (marked, *it);
	}
	return result;
}

void calculate_groups (Mset &s, int n)
{
	int c;
	Trit it;
	vector <bool> marked (n);
	s.clear();
	for_it (it, tree)
	{
		c = tree_dfs (marked, it->first);
		if (c > 0)
			s.insert (c);
	}
}


int all_pairs (int n)
{
	return n * (n - 1) / 2;
}


double probability (const Mset &s, double nn)
{
	Mit mit = prob.find (s);
	if (mit != prob.end())
		return mit->second;

	double &ps = prob[s];
	Msit it, jt, kt;

	for_it (it, s)
	{
		for (jt = it, ++jt; jt != s.end(); ++jt)
		{
			Mset saux;
			double paux = nn * (double) *it * (double) *jt;
			saux.insert (*it + *jt);
			for_it (kt, s)
			{
				if (kt != it && kt != jt)
					saux.insert (*kt);
			}
			paux *= probability (saux, nn);
			ps += paux;
		}
	}

	return ps;
}


int main ()
{
	int n, m, u, v;
	Mset s;
	double p, e;

	while (cin >> n >> m, !cin.fail())
	{
		init (n);
		while (m--)
		{
			cin >> u >> v;
			--u; --v;
			if (u > v)
				swap (u, v);
			tree[u].insert (v);
		}
		calculate_groups (s, n);
		p = probability (s, 1.0 / (double) all_pairs (n));
		e = p == 1.0 ? 0.0 : 1.0 / p;
		cout << e << endl;
	}

	return 0;
}